import os

from sc_engine.apps import messages as msgs
from sc_engine.repositories import Repository, use
from sc_engine.repositories.stores import PickleFileStore
from sc_engine.apps.video_game_linking.game_search_repository import GameSearchRepository

def make_app(app_name, root_config, config):
    data_dir= root_config['data_directory']

    store_filename = os.path.join(data_dir, app_name)
    store = PickleFileStore(store_filename)

    repo = Repository(store)

    app = VideoGameLinkApp(repo)

    return {
        msgs.ManualYouTubeLinkAnnouncement : app.manual_youtube_link_announcement,
        msgs.ProleagueMatchIdAnnouncement: app.proleague_match_id_announcement,
        msgs.ProleagueMatchIdAnnouncement: app.proleague_match_id_announcement,
        msgs.GameDataAnnouncement: app.game_data_announcement,
        msgs.YouTubeParseAnnouncement: app.youtube_parse_announcement,
    }

class VideoGameLinkApp(object):
    """Determine what game (if any) a video is a commentary of.

    Collects data for the matches and games being played to form a database of
    games. Will compare any video against this database to determine what game,
    if any, we believe that video to be a commentary of.
    """

    def __init__(self, repo):
        self.repo = repo
        repo.add_repository('games', GameSearchRepository)

    @use('repo', 'manual_links')
    def manual_youtube_link_announcement(self, msg, manual_links):
        key = msg.video_id
        data = {
            'match_id' : msg.match_id,
            'part_number' : msg.part_number,
            'game_number' : msg.game_number,
        }

        manual_links[key] = data
        return msgs.YouTubeVideoFetchRequested(msg.video_id)

    @use('repo', 'games')
    def proleague_match_id_announcement(self, msg, games):
        games.add_proleague_match(msg.match_id, msg.league, msg.stage_path,
                msg.team_one, msg.team_two)

    @use('repo', 'games')
    def game_data_announcement(self, msg, games):
        # Don't record info about unnecessary games
        if msg.player_one == None and msg.player_two == None:
            return

        games.set_game(msg.match_id, msg.game_number,
                msg.date_played, msg.player_one, msg.player_two)

    def _make_manual_link_announcement(self, manual_links, msg):
        info = manual_links[msg.video_id]

        return msgs.VideoGameLinkAnnouncement(
            info['match_id'], info['game_number'],
            msg.video_id, msg.author, msg.part_number
        )

    @use('repo', 'manual_links', 'games')
    def youtube_parse_announcement(self, msg, manual_links, games):
        if msg.video_id  in manual_links:
            return self._make_manual_link_announcement(manual_links, msg)

        # If there is no date played, team, or player, then it's probably not
        # even a video of a proleague game. This check will probably change over
        # time as needed.
        if msg.date_played == [] and msg.teams == [] and msg.players == []:
            return

        results = []

        specification = {
            'date_played' : msg.date_played,
            'teams' : msg.teams,
            'players' : msg.players,
            'game_number' : msg.game_number,
        }
            
        result = games.find_game(specification)

        if result.found:
            return msgs.VideoGameLinkAnnouncement(video_id=msg.video_id,
                    author=msg.author, part_number=msg.part_number,
                    **result.data)
        else:
            return msgs.YouTubePartialParseAnnouncement(msg.video_id, msg.title,
                    **result.data)

